piXoneer Development Library
XDL 3.0 for C#
NXImageView를 활용하여 위성영상 샘플의 특정 밴드를 선택해 RGB나 Gray로 도시하는 프로그램을 만드는 방법에 대해서 설명합니다.
“만들기” 버튼을 누르면 프로젝트가 기본적으로 생성되고, 화면에 Form을 디자인할 수 있는 화면이 생성된다. 만약 아래와 같이 Form 디자인화면이 생성되지 않으면, [솔루션 탐색기] 창에서 “Form1.cs”를 마우스 더블 클릭하여 디자인화면을 연다.
[도구 상자] 창에서 마우스 오른쪽 버튼을 클릭하여 생성되는 팝업메뉴에서 “항목 선택” 메뉴를 선택한다.
메뉴를 선택하면 아래와 같이 [도구 상자 항목 선택] 대화상자가 나타나며, 대화상자 아래쪽에 있는 “찾아보기” 버튼을 클릭한다.
열기 대화상자에서 “C:\Pixoneer\XDL3.0\bin\NXImage.dll” 파일을 선택한 후 “열기”를 클릭하고, [도구 상자 항목 선택] 대화상자의 “확인” 버튼을 클릭한다.
.NET Framework 구성요소 탭에 다양한 레이어와 NXImageView가 설정된다. “확인” 버튼을 클릭한다.
[도구 상자] 에 다양한 NXImageLayer들과 NXImageView가 추가됨을 확인한다.
폼 상단에 메뉴가 추가된 것을 확인할 수 있다.
Fom1.Designer.cs에서 보면 다음과 같이 컨트롤 nxImageView1 멤버변수가 추가됨을 확인할 수 있다. NXImageView는 다양한 NXImageLayerXXXXX들을 담을 수 있는 컨테이너이다. 즉, NXImageView는 다양한 계층의 레이어로 구성하여 영상도시에 대한 다양한 기능을 구현 가능하다.
C#
private System.Windows.Forms.MenuStrip menuStrip1;
private Pixoneer.NXDL.NXImage.NXImageView nxImageView1;
Fom1.Designer.cs에서 보면 다음과 같이 컨트롤 nxImageLayerComposites1 멤버변수가 추가됨을 확인할 수 있다. NXImageLayerComposites은 영상의 밴드들을 합성하여 화면에 도시하는 기능을 수행하는 컨트롤이다.
C#
private System.Windows.Forms.MenuStrip menuStrip1;
private Pixoneer.NXDL.NXImage.NXImageView nxImageView1;
private Pixoneer.NXDL.NXImage.NXImageLayerComposites nxImageLayerComposites1;
C#
using Pixoneer.NXDL; // 기본 함수 관련 기능
using Pixoneer.NXDL.NIO; // 파일 입출력 관련 기능
using Pixoneer.NXDL.NRS; // Remote Sensing 관련 기능
using Pixoneer.NXDL.NXImage; // ImageView 관련 기능
using Microsoft.Win32; // 파일 열기/저장 대화상자(OpenFileDialog, SaveFileDialog) 관련 클래스 사용을 위해 추가
C#
public partial class Form1 : Form
{
public XRasterIO m_RasterIO; //영상의 입출력을 담당할 객체 선언
public Form1()
{
InitializeComponent();
String StrError;
m_RasterIO = new XRasterIO(); // 객체 생성
if (m_RasterIO.Initialize(out StrError) == false) // 영상 입출력 객체 초기화
{
MessageBox.Show(StrError);
}
nxImageLayerComposites1.LayerVisible = true; // 영상레이어를 보이도록 속성을 변경
}
}
C#
private void OpenToolStripMenuItem_Click(object sender, EventArgs e)
{
// 1. 파일 Open을 수행한다.
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "XDM file(*.xdm)|*.XDM||";
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() != DialogResult.OK) return;
string strFilePath = openFileDialog.FileName;
// 2. XRSLoadFile을 생성한다.
string strError;
XRSLoadFile xrsFileInput = m_RasterIO.LoadFile(strFilePath, out strError, false, eIOCreateXLDMode.All_NoMsg);
if (xrsFileInput == null) return;
// 3. 기존에 생성되어 있는 Composite가 있다면 Lock을 걸어 도시 수행을 잠시 멈춘다.
nxImageLayerComposites1.Lock();
// 4. nxImageLayerComposites1 객체에 있는 XDMCompManager를 꺼낸다. XDMCompManager가 실제로 Composite들의 관리를 수행한다.
XDMCompManager xdmCompManager = nxImageLayerComposites1.GetXDMCompManager();
// 5. 기존에 Composite가 있다면 모두 삭제한다.
for (int i = 0; i < xdmCompManager.NumComp; i++)
{
XDMComposite comp = xdmCompManager.GetXDMCompositeAt(i);
comp.Dispose();
}
xdmCompManager.RemoveXDMCompositeAll();
// 6. XDMComposite를 생성한다.
XDMComposite newComp = new XDMComposite();
// 7. 로딩된 파일로 부터 밴드의 갯수가 칼라로 그릴것인지 흑백으로 그릴것인지를 판단한다.
// 만약 3개 미만인 경우는 Gray모드로 그리고, 3개 이상인 경우는 칼라로 그린다.
int nNumBand = xrsFileInput.NumBand;
if (nNumBand < 3) // 3개 미만의 밴드를 가지고 있는 경우
{
// Default로 0번째 밴드를 Gray모드로 그린다.
XDMBand band = xrsFileInput.GetBandAt(0);
// 밴드 이름을 그대로 Composite이름으로 설정
newComp.Name = band.BandName;
// Gray Mode로 그리는것을 설정
newComp.Mode = eCompMode.Gray;
// Composite의 0번에 Band설정, Gray모드에서는 0번 밴드만을 인식한다.
newComp.SetBand(ref band, 0);
// 영상 Enhancement를 위해 Histogram의 범위 설정(정규분포 95% 영역)
newComp.SetCutType(eCompCutType.Ct95, 0);
// 영상 Enhancement를 위해 Histogram적용시 전체 영역에 대한 Histogram(Band)설정, Visible은 현재 영역
newComp.SetStretchCoverage(eCompStretchCoverage.Band, 0);
// 영상 Enhancement를 위해 Histogram의 Stretch형태 설정(Gaussian으로 설정)
newComp.SetStretchType(eCompStretchType.Gaussian, 0);
}
else // 3개 이상의 밴드를 가지고 있는 경우
{
XDMBand band1 = xrsFileInput.GetBandAt(0);
XDMBand band2 = xrsFileInput.GetBandAt(1);
XDMBand band3 = xrsFileInput.GetBandAt(2);
newComp.Name = xrsFileInput.FileName; // 파일 이름을 Compoiste이름으로 설정
newComp.Mode = eCompMode.RGB; // RGB Mode로 그리는것을 설정
newComp.SetBand(ref band3, 0); // Composite의 0번에 Band설정, Blue Channel설정
newComp.SetBand(ref band2, 1); // Composite의 1번에 Band설정, Green Channel설정
newComp.SetBand(ref band1, 2); // Composite의 2번에 Band설정, Red Channel설정
for (int i = 0; i < 3; i++)
{
// 영상 Enhancement를 위해 Histogram의 범위 설정(정규분포 95% 영역)
newComp.SetCutType(eCompCutType.Ct95, i);
// 영상 Enhancement를 위해 Histogram적용시 전체 영역에 대한 Histogram(Band)설정, Visible은 현재 영역
newComp.SetStretchCoverage(eCompStretchCoverage.Band, i);
// 영상 Enhancement를 위해 Histogram의 Stretch형태 설정(Gaussian으로 설정)
newComp.SetStretchType(eCompStretchType.Gaussian, i);
}
}
// 8. 생성된 Composite를 XDMCompManger객체에 추가한다.
xdmCompManager.AddXDMComposite(ref newComp);
// 9. 전체 화면 보기를 설정한다.
nxImageLayerComposites1.ZoomFit();
// 10. 화면 업데이트를 수행한다.
nxImageLayerComposites1.Invalidate();
// 11. 설정된 Lock를 해제한다.
nxImageLayerComposites1.UnLock();
}
“만들기” 버튼을 누르면 프로젝트가 기본적으로 생성되고 화면에 Window을 디자인할 수 있는 화면이 뜬다. 만약 아래와 같은 Window 창이 생성되지 않으면, [솔루션 탐색기] 창에서 MainWindow.xaml”를 마우스 더블클릭 하여 창을 연다.
XAML
xmlns:nxImage="clr-namespace:Pixoneer.NXDL.NXImage;assembly=NXImage"
XMAL
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
</Grid>
[도구 상자]에서 Menu 컨트롤을 Window창에 배치한다.
Menu가 Window에 배치된 것을 확인하고 Menu를 오른쪽 버튼을 눌러 MenuItem을 추가한다.
상단 메뉴에서 [보기]-[속성 창]을 눌러 “속성 창”으로 이동한 다음 Header에 “_File”을 입력한다.
아래와 같은 메뉴가 생성됐음을 확인한다.
다음으로 [File]을 오른쪽 버튼을 클릭하고 MenuItem을 추가한다. XAML에서 File에 MenuItem이 생성된 것을 확인할 수 있다. 생성된 MenuItem의 [속성] 창에 Header를 “_Open”으로 입력하고, 이름은 “openFileMenuItem”으로 정의한다.
실행하면 다음과 같은 Window 창이 생성된다.
최종적으로 다음과 같은 XAML 코드를 생성한다.
XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<MenuItem Header="_File" Margin="5,5,0,0">
<MenuItem x:Name="openFileMenuItem" Header="_Open"/>
</MenuItem>
</Menu>
</Grid>
XAML
<Grid Grid.Row="1">
<WindowsFormsHost Margin="3,0,0,3" >
</WindowsFormsHost>
</Grid>
WindowFormsHost창의 크기를 변화시켜 두 번째 Row Grid창에 맞게 조정한다. 그 결과로 다음과 같은 Window 창을 얻을 수 있다.
NXImageView는 다양한 NXImageLayerXXXXX들을 담을수 있는 컨테이너이다. 즉, NXImageView는 다양한 계층의 레이어로 구성하여 영상도시에 대한 다양한 기능을 구현이 가능하다.
XAML
<Grid Grid.Row="1">
<WindowsFormsHost Margin="3,0,0,3" >
<nxImage:NXImageView x:Name="nxImageView1">
</nxImage:NXImageView>
</WindowsFormsHost>
</Grid>
NXImageLayerComposites은 영상의 밴드들을 색합성하여 화면에 도시하는 기능을 수행하는 컨트롤이다.
XAML
<Grid Grid.Row="1">
<WindowsFormsHost Margin="3,0,0,3">
<nxImage:NXImageView x:Name="nxImageView1">
<nxImage:NXImageView.Controls>
<nxImage:NXImageLayerComposites x:Name="nxImageLayerComposites1"/>
</nxImage:NXImageView.Controls>
</nxImage:NXImageView>
</WindowsFormsHost>
</Grid>
최종적으로 다음과 같은 XAML 코드를 생성한다.
XAML
<Window x:Class="XDL_ImageView1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:XDL_ImageView1"
xmlns:nxImage="clr-namespace:Pixoneer.NXDL.NXImage;assembly=NXImage"
mc:Ignorable="d"
Title="ImageView1" Height="450" Width="450" Closed="Window_Closed">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<MenuItem Header="_File" Margin="5,5,0,0">
<MenuItem x:Name="openFileMenuItem" Header="_Open" />
</MenuItem>
</Menu>
<Grid Grid.Row="1">
<WindowsFormsHost Margin="3,0,0,3">
<nxImage:NXImageView x:Name="nxImageView1">
<nxImage:NXImageView.Controls>
<nxImage:NXImageLayerComposites x:Name="nxImageLayerComposites1"/>
</nxImage:NXImageView.Controls>
</nxImage:NXImageView>
</WindowsFormsHost>
</Grid>
</Grid>
</Window>
XAML 디자이너에서 openFileMenuItem을 클릭한다. [속성] 창에서 [이벤트] 탭을 선택한 후, Click 이벤트란을 더블 클릭하면 코드 비하인드에 자동으로 함수가 생성된다.
아래와 같은 함수가 MainWindow.xaml.cs 코드 비하인드에 추가된다.
C#
private void openFileButton_Click(object sender, RoutedEventArgs e)
{
}
또는 XAML디자이너에 직접 Click 이벤트를 추가하고, 이후 openFileMenuItem_Click 에 대해 “정의로 이동” 을 클릭하면 MainWindow.xaml.cs 코드 비하인드에 함수가 생성된다.
XAML
<Menu Grid.Row="0">
<MenuItem Header="_File" Margin="5,5,0,0">
<MenuItem x:Name="openFileMenuItem" Header="_Open" Click="openFileMenuItem_Click"/>
</MenuItem>
</Menu>
C#
using Pixoneer.NXDL; // 기존 함수 관련 기능
using Pixoneer.NXDL.NIO; // 파일 입출력 관련기능
using Pixoneer.NXDL.NRS; // Remote Secsing 관련기능
using Pixoneer.NXDL.NXImage; // ImageView 관련 기능
using Microsoft.Win32; // 파일 열기/저장 대화상자(OpenFileDialog, SaveFileDialog) 관련 클래스 사용을 위해 추가
아래와 같이 NXImageView 관련 기능 해제를 위해서 코드를 추가한다.
C#
private void Window_Closed(object sender, EventArgs e)
{
Xfn.Close();
}
C#
public partial class MainWindow : Window
{
public XRasterIO m_RasterIO; // 영상의 입출력을 담당할 객체 선언
public MainWindow()
{
InitializeComponent();
String StrError;
m_RasterIO = new XRasterIO(); // 객체 생성
if(m_RasterIO.Initialize(out StrError) == false) // 영상 입출력 객체 초기화
{
MessageBox.Show(StrError);
}
nxImageLayerComposites1.LayerVisible = true;//영상 레이어를 보이도록 속성을 변경
}
}
C#
private void openFileMenuItem_Click(object sender, RoutedEventArgs e)
{
// 1. 파일 Open을 수정한다.
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "XDM file(*.xdm)|*.XDM||";
openFileDialog.RestoreDirectory = true;
Nullable<bool> result = openFileDialog.ShowDialog();
if (result != true) return;
string strFilePath = openFileDialog.FileName;
// 2. FileDriverManger를 통해 XRSLoadFile을 생성한다.
string strError;
XRSLoadFile xrsFileInput = m_RasterIO.LoadFile(strFilePath, out strError, false, eIOCreateXLDMode.All_NoMsg);
if (xrsFileInput == null) return;
// 3. 기존에 생성되어 있는 Composite가 있다면 Lock을 걸어 도시 수행을 잠시 멈춘다.
nxImageLayerComposites1.Lock();
// 4. nxImageLayerComposites1개체에 있는 XDMCompManager를 꺼낸다.
// XDMCompManager가 실제로 Composite들의 관리를 수행한다.
XDMCompManager xdmCompManager = nxImageLayerComposites1.GetXDMCompManager();
// 5. 기존에 Composite가 있다면 모두 삭제한다.
for (int i = 0; i < xdmCompManager.NumComp; i++)
{
XDMComposite comp = xdmCompManager.GetXDMCompositeAt(i);
comp.Dispose();
}
xdmCompManager.RemoveXDMCompositeAll();
// 6. XDMComposite를 생성한다.
XDMComposite newComp = new XDMComposite();
// 7. 로딩된 파일로부터 밴드의 개수를 칼라로 그릴 것인지 흑백으로 그릴 것인지를 판단한다.
// 만약 3개 미만인 경우는 Gray모드로 그리고, 3개 이상인 경우는 칼라로 그린다.
int nNumBand = xrsFileInput.NumBand;
if (nNumBand < 3)
{
// Default로 0번째 밴드를 Gray모드로 그린다.
XDMBand band = xrsFileInput.GetBandAt(0);
// 밴드 이름을 그대로 Composite이름으로 설정
newComp.Name = band.BandName;
// Gray Mode로 그리는 것을 설정
newComp.Mode = eCompMode.Gray;
// Composite의 0번에 Band설정, Gray모드에서는 0번 밴드만을 인식한다.
newComp.SetBand(ref band, 0);
// 영상 Enhancement를 위해 Histogram의 범위 설정(정규분포 95% 영역)
newComp.SetCutType(eCompCutType.Ct95, 0);
// 영상 Enhancement를 위해 Histogram적용시 전체 영역에 대한
// Histogram(Band)설정, Visible은 현재 영역
newComp.SetStretchCoverage(eCompStretchCoverage.Band, 0);
// 영상 Enhancement를 위해 Histogram의 Stretch형태 설정(Gaussian으로 설정)
newComp.SetStretchType(eCompStretchType.Gaussian, 0);
}
else // 3개 이상의 밴드를 가지고 있는 경우
{
XDMBand band1 = xrsFileInput.GetBandAt(0);
XDMBand band2 = xrsFileInput.GetBandAt(1);
XDMBand band3 = xrsFileInput.GetBandAt(2);
newComp.Name = xrsFileInput.FileName; //파일 이름을 Composite 이름으로 설정
newComp.Mode = eCompMode.RGB; // RGB Mode로 그리는 것을 설정
newComp.SetBand(ref band3, 0); // Composite의 0번에 Band설정, Blue Channel 설정
newComp.SetBand(ref band2, 1);// Composite의 1번에 Band설정, Green Channel 설정
newComp.SetBand(ref band1, 2); // Composite의 2번에 Band설정, Red Channel 설정
for (int i = 0; i < 3; i++)
{
// 영상 Enhancement를 위해 Histogram의 범위 설정(정규분포 95% 영역)
newComp.SetCutType(eCompCutType.Ct95, i);
// 영상 Enhancement를 위해 Histogram적용 시 전체 영역에 대한
// Histogram(Band)설정, Visible은 현재 영역
newComp.SetStretchCoverage(eCompStretchCoverage.Band, i);
// 영상 Enhancemnet를 위해 Histogram의 Stretch형태 설정(Gaussian으로 설정)
newComp.SetStretchType(eCompStretchType.Gaussian, i);
}
}
// 8. 생성된 Composite를 XDMCompManager객체에 추가한다.
xdmCompManager.AddXDMComposite(ref newComp);
// 9. 전체 화면 보기를 설정한다.
nxImageLayerComposites1.ZoomFit();
// 10. 화면 업데이트를 수행한다.
nxImageLayerComposites1.Invalidate();
// 11. 설정된 Lock를 해제한다.
nxImageLayerComposites1.UnLock();
}